package com.self.cloudmall.wms.config;

import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.annotation.PostConstruct;
import java.util.Map;

@Slf4j
@Configuration
public class RabbitMqConfig {
    @Autowired
    private RabbitTemplate rabbitTemplate;

    /**
     * 消息序列化机制，消息转换为json
     * @return
     */
    @Bean
    public MessageConverter messageConverter(){
        return new Jackson2JsonMessageConverter();
    }

    @PostConstruct
    public void init(){
        //消息抵达交换机回调方法
        /**
         * correlationData:消息关联数据，可以设置唯一ID
         * isAck：是否确认成功，
         * error：错误信息
         */
        rabbitTemplate.setConfirmCallback((correlationData,isAck,error)->{
            if (!isAck){
                log.error("库存-correlationData:{},消息没有确认，错误信息：{}",correlationData,error);
            }
            log.info("库存-correlationData:{},消息确认完成",correlationData);
        });
        //消息抵达队列回调方法
        /**
         * message：消息
         * replayCode：回复状态码
         * replayText：回复文本
         * exchange：消息来自于的交换机
         * routingKey：消息用的路由键
         */
        rabbitTemplate.setReturnCallback((Message message, int replayCode, String replayText, String exchange, String routingKey) ->{
            log.info("库存-消息：{}，回复状态码：{}，回复文本：{}，消息来自于的交换机：{}，消息用的路由键：{}",message,
                    replayCode,replayText,exchange,routingKey);
        });
    }

    /**
     * 释放库存队列
     * @return
     */
    @Bean
    public Queue releaseStockQueue(){
        return new Queue("stock.release.queue",true,false,false);
    }

    /**
     * 库存延时队列
     * @return
     */
    @Bean
    public Queue stockDelayQueue(){
        Map<String, Object> args = Maps.newHashMap();
        args.put("x-dead-letter-exchange","stock-event-exchange");
        args.put("x-dead-letter-routing-key","stock.release");
        //消息过期时间，默认单位是毫秒
        args.put("x-message-ttl",120000);
        return new Queue("stock.delay.queue",true,false,false,args);
    }

    /**
     * 创建交换机
     * @return
     */
    @Bean
    public Exchange stockEventExchange(){
        return new TopicExchange("stock-event-exchange",true,false);
    }

    /**
     * 释放库存绑定到交换器上
     * @return
     */
    @Bean
    public Binding releaseStockBinding(){
        return new Binding("stock.release.queue", Binding.DestinationType.QUEUE,
                "stock-event-exchange","stock.release.#",null);
    }

    /**
     * 库存延时队列绑定到交换器上
     * @return
     */
    @Bean
    public Binding stockDelayBinding(){
        return new Binding("stock.delay.queue", Binding.DestinationType.QUEUE,
                "stock-event-exchange","stock.lock",null);
    }

    /**
     * 订单释放，自动解锁库存
     * @return
     */
    @Bean
    public Binding orderReleaseOtherBinding(){
        return new Binding("stock.release.queue", Binding.DestinationType.QUEUE,
                "order-event-exchange","order.release.other.#",null);
    }


}
